#include "PdfUtil.h"
#include <fstream>
#include <iostream>
#include <mupdf/fitz/outline.h>
#include <mupdf/fitz/output.h>
#include <tuple>
#include <vector>
#include <optional>
#include <mupdf/pdf.h>
#include <mupdf/pdf/document.h>
#include <mupdf/fitz.h>
#include <mupdf/fitz/context.h>
#include "MuDraw.h"

void PdfUtil::testDraw(){
   char* argv[] {
       "mudraw","-F","png",
        "/data/data/com.termux/files/home/storage/downloads/books/manual.pdf",
        "17,28,39"
   };
   int argc = 5;
   std::vector<std::string> & rets = mudraw_main(argc, argv);
   std::cout<<"draw ret"<<rets.size()<<std::endl;
}
int PdfUtil::cid = 0;

void get_outline(fz_outline *outline, int level,fz_context* ctx,std::vector<Toc> & vec,int pcid = 0)
{
    int i;
    auto out = fz_stdout(ctx);
    while (outline)
    {
        PdfUtil::cid++ ;                    // add page with 1
        Toc toc(outline->title,outline->uri,outline->page.page+1,level,PdfUtil::cid,pcid);
        vec.push_back(toc);

        // has child? handle it
        if (outline->down)
            get_outline(outline->down, level + 1,ctx,vec,PdfUtil::cid);

        // handle next
        outline = outline->next;
    }
}

std::vector<Toc> PdfUtil::getPdfToc(const char * filename){
    std::vector<Toc> vec;
    fz_context * ctx = nullptr;
    ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
    if(!ctx){
      std::cout<<" create context error"<<std::endl;
      return vec;
    }
    //char  filename[] {"/data/data/com.termux/files/home/storage/downloads/books/manual.pdf"};
    fz_try(ctx){
       pdf_document* doc =  pdf_open_document(ctx, filename);
       if(doc == nullptr){
          std::cout<<"document is null"<<std::endl;
       }else{
          fz_outline *outline = fz_load_outline(ctx, (fz_document*)doc);

          fz_try(ctx)
              get_outline(outline, 1,ctx,vec);
          fz_always(ctx)
              fz_drop_outline(ctx, outline);
          fz_catch(ctx)
              fz_rethrow(ctx);

          return vec;
       }
    }
    fz_catch(ctx)
    {
        return vec;
    }
    return vec;
}

void print_outline(fz_outline *outline, int level,fz_context* ctx)
{
    int i;
    auto out = fz_stdout(ctx);
    while (outline)
    {
        // has child ?
        if (outline->down)
            fz_write_byte(ctx, out, outline->is_open ? '-' : '+');
        else
            fz_write_byte(ctx, out, '|');

        // write current level tab
        for (i = 0; i < level; i++)
            fz_write_byte(ctx, out, '\t');

        // write info
        fz_write_printf(ctx, out, "%Q\t%s\n", outline->title, outline->uri);

        // has child? handle it
        if (outline->down)
            print_outline(outline->down, level + 1,ctx);

        // handle next
        outline = outline->next;
    }
}

void PdfUtil::testPdf(){
    fz_context * ctx = nullptr;
    ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
    if(!ctx){
      std::cout<<" create context error"<<std::endl;
      return;
    }
    char  filename[] {"/data/data/com.termux/files/home/storage/downloads/books/manual.pdf"};
    fz_try(ctx){
       pdf_document* doc =  pdf_open_document(ctx, filename);
       if(doc == nullptr){
          std::cout<<"document is null"<<std::endl;
       }
        fz_outline *outline = fz_load_outline(ctx, (fz_document*)doc);
        fz_try(ctx)
            print_outline(outline, 1,ctx);
        fz_always(ctx)
            fz_drop_outline(ctx, outline);
        fz_catch(ctx)
            fz_rethrow(ctx);

    }
    fz_catch(ctx)
    {
        return ;
    }
}



